import json
import logging
import os
import subprocess
from datetime import datetime

from flask import Flask, abort, request

app = Flask(__name__)
config_file= "config.json"

def exec_cmd(cmd:list,pwd:str):
    cwd = os.getcwd()
    try: 
        os.chdir(pwd)
    except FileNotFoundError as ffe:
        logging.error(f"Fail to chdir, {ffe}!")
        return "Fail to chdir!"
    com = subprocess.run(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    os.chdir(cwd)
    if com.returncode != 0:
        return com.stderr
    else:
        return ""

def pull(repo:str,branch:str,passwd:str):
    config= {}
    path=""
    with open("config.json") as f:
        config = json.load(f)
    if config[repo]['passwd']!=passwd:
        logging.error("Password Mismatch!")
        return False
    else:
        path = config[repo][branch]['path']
    cmd=["git","pull"]
    logging.info(f"Executing {cmd} at {path}")
    r = exec_cmd(cmd,path)
    if r:
        logging.error("Command exec fail")
        return False
    else :
        return True
@app.route('/update',methods=[ 'POST'])
def update():
    data = request.json
    ua = request.headers.get('User-Agent',None)
    logging.debug(f"User-Agent {ua}")
    if ua !="git-oschina-hook":
        logging.error("UA error.")
        abort(404)
    if data ==None:
        logging.error("Empty Body")
        abort(404)
    try :
        repository = data['repository']['name']
        branch = data['ref'].split("/")[-1]
        message = data['head_commit']['message']
        author = data['head_commit']['author']['name']
        passwd = data['password']
        logging.info(f"{author} commits {repository} ,branch: {branch}\n{message}")
    except KeyError as ke:
        logging.error("Some key not found")
        logging.debug(ke)
        abort(403)
    if pull(repository,branch,passwd):
        return "Success"
    else:
        return "Fail"

def main():
    from sys import argv
    import argparse
    parser = argparse.ArgumentParser(description='Git WebHook Auto Depoly')
    parser.add_argument('-d','--debug',help='设置日志文件级别为debug',action='store_true')
    parser.add_argument('-c','--config-file',type=str,help='配置文件',default='data.json',nargs='?')
    args = parser.parse_args()
    if args.debug:
        level = logging.DEBUG
    else:
        level = logging.INFO
    config_file = args.config_file
    # TODO 添加配置类,用于存放配置. 配置为整个项目的配置,仓库配置单独放在里面另一个文件里
    logging.basicConfig(level=level,
                        format="[%(levelname)s] %(funcName)s %(message)s")
    logging.debug("DEBUG MODE ON")
    app.run("0.0.0.0")

if __name__ == '__main__':
    
    main()
